﻿using Digitalmes.Application.Sys.Menus;

namespace Digitalmes.Application.Sys.Users.Services.Impl;

internal sealed class UserMenuApplicationService(IRepository<SysUser> userRepo) : IUserMenuApplicationService
{
    public async Task<List<SysMenuDto>> GetMenuListByUserIdAsync(long userId)
    {
        int[] menuTypes = [0, 1]; // 菜单类型，只包含目录和菜单。

        var result = await userRepo.AsQueryable()
            .InnerJoin<SysUserRole>((u, ur) => ur.UserId == u.Id)
            .InnerJoin<SysRole>((u, ur, r) => r.Id == ur.RoleId && r.Status == EnabledStatusEnum.Enabled && r.IsDeleted == false)
            .InnerJoin<SysRoleMenu>((u, ur, r, rm) => r.Id == rm.RoleId)
            .InnerJoin<SysMenu>((u, ur, r, rm, m) => m.Id == rm.MenuId && menuTypes.Contains(m.Type))
            .Where((u, ur, r, rm, m) => u.Id == userId)
            .Select((u, ur, r, rm, m) => m)
            .ToListAsync();

        return result.Adapt<List<SysMenuDto>>();
    }

    public async Task<string[]> GetPermissionCodesByUserIdAsync(long userId)
    {
        var result = await userRepo.AsQueryable()
            .InnerJoin<SysUserRole>((u, ur) => ur.UserId == u.Id)
            .InnerJoin<SysRole>((u, ur, r) => r.Id == ur.RoleId && r.Status == EnabledStatusEnum.Enabled && r.IsDeleted == false)
            .InnerJoin<SysRoleMenu>((u, ur, r, rm) => r.Id == rm.RoleId)
            .InnerJoin<SysMenu>((u, ur, r, rm, m) => m.Id == rm.MenuId && !string.IsNullOrEmpty(m.Permission))
            .Where((u, ur, r, rm, m) => u.Id == userId)
            .Select((u, ur, r, rm, m) => m.Permission)
            .ToListAsync();

        return result
            .Where(s => !string.IsNullOrWhiteSpace(s))
            .Select(s => s!)
            .Distinct()
            .ToArray();
    }
}
